package com.hengpeng.itfin.sms.impl;

import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.hengpeng.common.cis.ComponentContextLoader;
import com.hengpeng.common.exception.ServiceResult;
import com.hengpeng.common.util.MD5;
import com.hengpeng.common.web.rest.RestClient;
import com.hengpeng.itfin.service.ServiceFactory;
import com.hengpeng.itfin.sms.AbstractGatewayProcessor;
import com.hengpeng.itfin.sms.SmsPartnerService;
import com.hengpeng.itfin.sms.vo.MTHttpRequestMessage;
import com.hengpeng.itfin.sms.vo.MTHttpResponseMessage;
import com.hengpeng.itfin.sms.vo.MessagePackage;
import com.hengpeng.itfin.sms.vo.MessageType;
import com.hengpeng.itfin.sms.vo.ResponseCode;
import com.hengpeng.itfin.sms.vo.TransMessage;
import com.hengpeng.itfin.sms.vo.TransType;
import com.hengpeng.itfinbase.persist.SmsLog;
import com.hengpeng.itfinbase.persist.SmsPartner;

public class SmsHsapServiceImpl extends AbstractGatewayProcessor
{
	public static final String JSON_DATETIME_FORMAT = "yyyyMMddHHmmss";

	private final static Log logger = LogFactory.getLog(SmsHsapServiceImpl.class);

	/**
	 * 系统参数名-短信接口地址
	 */
	public static final String SMSPORT_URL = "URL";

	/**
	 * 系统参数名-短信接口商户号
	 */
	public static final String SMSPORT_PARTNERID = "PARTNERID";

	/**
	 * 系统参数名-短信接口密码
	 */
	public static final String SMSPORT_PWD = "PWD";

	public ServiceFactory serviceFactory = null;

	private final RestTemplate restTemplate;

	private static final GsonBuilder gsonBuilder = createGson();

	public SmsHsapServiceImpl(ApplicationContext context, SmsPartner partner)
	{
		super(context, partner);
		List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
		converters.add(new MappingJacksonHttpMessageConverter());
		restTemplate = new RestTemplate();
		restTemplate.setMessageConverters(converters);
		serviceFactory = context.getBean(ServiceFactory.class);
	}

	@SuppressWarnings("unchecked")
	private <T> T doPostTrans(TransType transType, Class<T> returnType, TransMessage parameter, Object... pathValue)
	{
		String smsporturl = partner.getExtConfigs().get(SMSPORT_URL);
		String partnerId = partner.getExtConfigs().get(SMSPORT_PARTNERID);
		String pwd = partner.getExtConfigs().get(SMSPORT_PWD);
		RestClient restclient = new RestClient(restTemplate, partnerId, pwd);

		try
		{
			Gson create = gsonBuilder.create();
			String json = create.toJson(parameter);
			String date = formatDate(JSON_DATETIME_FORMAT, new Date());

			long messageSeq = serviceFactory.getSequenceService().getSequence("SmsHsapMessageSequence");
			String messageId = partnerId + formatDate("yyyyMMdd", new Date()) + messageSeq;
			String md5Hex = MD5
					.encodeString(partnerId + "#" + pwd + "#" + messageId + "#" + date + "#" + json, "UTF-8");
			MessagePackage messagePackage = new MessagePackage(partnerId, messageId, transType, date, md5Hex, json);
			// logger.info("请求JSON:" + create.toJson(messagePackage));
			ServiceResult<MessagePackage> execPost = restclient.execPost(smsporturl, MessagePackage.class,
					messagePackage);
			if (execPost.getIsSuccess())
			{
				MessagePackage returnValue = execPost.getReturnValue();
				// logger.info("返回JSON:" + create.toJson(returnValue));
				return (T) create.fromJson(returnValue.getBody(), transType.getResponseType());
			}
			else
			{
				logger.error("Remote service invoke error[" + execPost.getException().toString() + ":"
						+ execPost.getException().getMessage() + "]", execPost.getException());
				return null;
			}
		}
		catch (HttpServerErrorException e)
		{
			logger.error(
					"Remote service invoke error[" + e.toString() + ":" + e.getMessage() + "]{" + e.getStatusText()
							+ "}", e);
			return null;
		}
		catch (Exception e)
		{
			logger.error("Remote service invoke error[" + e.toString() + ":" + e.getMessage() + "]", e);
			return null;
		}
	}

	@Override
	public ServiceResult<SmsLog> sendMessage(SmsLog smsLog)
	{
		ServiceResult<SmsLog> result = new ServiceResult<SmsLog>();
		result.setReturnValue(smsLog);
		MTHttpRequestMessage lr = new MTHttpRequestMessage();
		lr.setMobile(new String[] { smsLog.getMobile() });
		lr.setContent(smsLog.getContent());
		lr.setType(MessageType.ANNOUNCEMENT);
		lr.setScheduleTime(new Date());
		lr.setPriority(3);
		lr.setPartnerId(String.valueOf(partner.getId()));
		lr.setId(String.valueOf(partner.getId()) + serviceFactory.getSequenceService().getSequence("SmsHsapMTSequence"));
		lr.setBizCode("021");
		lr.setNeedReport(false);
		MTHttpResponseMessage message = doPostTrans(TransType.MT, MTHttpResponseMessage.class, lr);
		if ((message != null) && (ResponseCode.SUCCESS.getCode().equals(message.getCode())))
		{
			result.setIsSuccess(true);
		}
		else
		{
			result.setIsSuccess(false);
		}
		return result;
	}

	public static GsonBuilder createGson()
	{
		GsonBuilder gsonBuilder = new GsonBuilder();
		gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>()
		{
			@Override
			public Date deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
					throws JsonParseException
			{
				try
				{
					SimpleDateFormat sdf = new SimpleDateFormat(JSON_DATETIME_FORMAT);
					return sdf.parse(json.getAsString());
				}
				catch (ParseException e)
				{
					throw new RuntimeException("日期格式不对,Pattern应该为:" + JSON_DATETIME_FORMAT, e);
				}
			}
		});
		gsonBuilder.registerTypeAdapter(Date.class, new JsonSerializer<Date>()
		{
			@Override
			public JsonElement serialize(Date arg0, Type arg1, JsonSerializationContext arg2)
			{
				SimpleDateFormat sdf = new SimpleDateFormat(JSON_DATETIME_FORMAT);
				return new JsonPrimitive(sdf.format(arg0));
			}
		});
		return gsonBuilder;
	}

	private static String formatDate(String pattern, Date date)
	{
		return new SimpleDateFormat(pattern, Locale.getDefault()).format(date);
	}

	public static void main(String[] args)
	{
		SmsPartnerService service = (SmsPartnerService) ComponentContextLoader.getBean("smsHsapServiceImpl");

		SmsLog smsLog = new SmsLog();
		smsLog.setContent("短信测试");
		smsLog.setMobile("13417429607");
		ServiceResult<SmsLog> result = service.sendMessage(smsLog);
		System.out.println(result.getIsSuccess());
	}

	@Override
	public void release()
	{
	}
}
